package com.anji.sp.push.service.impl;

import com.anji.sp.model.ResponseModel;
import com.anji.sp.push.model.MessageModel;
import com.anji.sp.push.model.po.PushConfiguresPO;
import com.anji.sp.push.model.po.PushUserPO;
import com.anji.sp.push.model.vo.PushUserVO;
import com.anji.sp.push.model.vo.RequestSendBean;
import com.anji.sp.push.service.PushHistoryService;
import com.anji.sp.push.service.PushService;
import com.anji.sp.push.service.PushUserService;
import com.anji.sp.util.APPVersionCheckUtil;
import com.anji.sp.util.StringUtils;
import com.vivo.push.sdk.notofication.InvalidUser;
import com.vivo.push.sdk.notofication.Message;
import com.vivo.push.sdk.notofication.Result;
import com.vivo.push.sdk.notofication.TargetMessage;
import com.vivo.push.sdk.server.Sender;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;


/**
 * <p>
 * vivo推送
 * </p>
 *
 * @author kean
 * @since 2021-01-20
 */
@Service
@Slf4j
public class VivoPushServiceImpl implements PushService {

    @Autowired
    private PushHistoryService pushHistoryService;
    @Autowired
    private JPushServiceImpl jPushService;
    @Value("${custom.push.vivo.mode:1}")
    private int customPushMode;

    @Autowired
    private PushUserService pushUserService;

    @Override
    public ResponseModel pushBatchMessage(RequestSendBean requestSendBean, PushConfiguresPO pushConfiguresPO, String msgId, String targetType) throws Exception {
        if (StringUtils.isEmpty(pushConfiguresPO.getVoAppSecret())
                || StringUtils.isEmpty(pushConfiguresPO.getVoAppId())
                || StringUtils.isEmpty(pushConfiguresPO.getVoAppKey())
                || StringUtils.isEmpty(pushConfiguresPO.getAppKey())) {
            //如果参数不全 那么走极光
            jPushService.pushAndroid(requestSendBean, pushConfiguresPO, msgId, "6", false);
            return ResponseModel.errorMsg("参数配置不全");
        }
        MessageModel messageModel;
        try {
            messageModel = pushSignleMessage(requestSendBean, pushConfiguresPO);
        } catch (Exception e) {
            //发送失败重新尝试一次
            messageModel = pushSignleMessage(requestSendBean, pushConfiguresPO);
        }
        //判断成功数是否是0
        if (APPVersionCheckUtil.strToInt(messageModel.getSuccessNum()) == 0){
            return jPushService.pushAndroid(requestSendBean, pushConfiguresPO, msgId, "6", false);
        }
        return pushHistoryService.savePushHistory(requestSendBean, messageModel, msgId, targetType);

    }

    @Override
    public ResponseModel pushAllMessage(RequestSendBean requestSendBean, PushConfiguresPO pushConfiguresPO, String msgId, String targetType) throws Exception {
        if (StringUtils.isEmpty(pushConfiguresPO.getVoAppSecret())
                || StringUtils.isEmpty(pushConfiguresPO.getVoAppId())
                || StringUtils.isEmpty(pushConfiguresPO.getVoAppKey())
                || StringUtils.isEmpty(pushConfiguresPO.getAppKey())) {
            //如果参数不全 那么走极光
            jPushService.pushAndroid(requestSendBean, pushConfiguresPO, msgId, "6", false);
            return ResponseModel.errorMsg("参数配置不全");
        }
        MessageModel messageModel;
        int attempts = 0;
        try {
            messageModel = pushAllMessage(requestSendBean, pushConfiguresPO);
        } catch (Exception e) {
            //发送失败重新尝试一次
            messageModel = pushAllMessage(requestSendBean, pushConfiguresPO);
        }
        //判断成功数是否是0
        if (APPVersionCheckUtil.strToInt(messageModel.getSuccessNum()) == 0){
            return jPushService.pushAndroid(requestSendBean, pushConfiguresPO, msgId, "6", false);
        } else {
            return pushHistoryService.savePushHistory(requestSendBean, messageModel, msgId, targetType);
        }
    }

    /**
     * 测试发送
     *
     * @param requestSendBean
     * @param pushConfiguresPO
     * @return
     */
    public MessageModel pushSignleMessage(RequestSendBean requestSendBean, PushConfiguresPO pushConfiguresPO) {
        try {
            Sender sender = new Sender(pushConfiguresPO.getVoAppSecret());//注册登录开发平台网站获取到的appSecret
            sender.initPool(20, 10);//设置连接池参数，可选项
            Result result = sender.getToken(Integer.parseInt(pushConfiguresPO.getVoAppId()), pushConfiguresPO.getVoAppKey());//注册登录开发平台网站获取到的appId和appKey
            sender.setAuthToken(result.getAuthToken());
            log.info("vivo.pushConfiguresPO: {}", pushConfiguresPO);
            log.info("vivo.pushConfiguresPO.customPushMode: {}", customPushMode);

            Message singleMessage = new Message.Builder()
                    //该测试手机设备订阅推送所得的regid，且已添加为测试设备
                    .regId(requestSendBean.getTokens().get(0))
                    .notifyType(3)
                    .extra("callback", "http://open-appsp.anji-plus.com/push/pushVivoCallBack")
                    .extra("callback.param", "Vivo回调自定义参数")
                    .title(requestSendBean.getTitle())
                    .content(requestSendBean.getContent().length() > 49 ? requestSendBean.getContent().substring(0, 49) : requestSendBean.getContent())
                    .timeToLive(1000)
                    .skipType(4)
                    .classification(1)//消息类型 0：运营类消息，1：系统类消息
                    .skipContent("vpushscheme://com.vivo.push.notifysdk/detail")
                    .clientCustomMap(requestSendBean.getExtras())
                    .networkType(-1)
                    .requestId("1234567890123456")
                    .pushMode(customPushMode)
                    .build();
            Result resultMessage = sender.sendSingle(singleMessage);

            jPushService.setPassThrougnMsg(requestSendBean, pushConfiguresPO);
            log.info("VivoPush.pushSignleMessage resultMessage {} ", resultMessage);
            InvalidUser invalidUser = resultMessage.getInvalidUser();
            String errStr = "";
            if (Objects.nonNull(invalidUser)){
                PushUserVO vo = new PushUserVO();
                vo.setAppKey(requestSendBean.getAppKey());
                vo.setManuToken(invalidUser.getUserid());
                ResponseModel responseModel = pushUserService.queryByMaunToken(vo);
                if (responseModel.isSuccess()) {
                    PushUserPO pushUserPO = (PushUserPO) responseModel.getRepData();
                    String e = "";
                    switch (invalidUser.getStatus()){
                        case 1:
                            e = "userId不存在";
                            break;
                        case 2:
                            e = "卸载或者关闭了通知";
                            break;
                        case 3:
                            e = "90天不在线";
                            break;
                        case 4:
                            e = "非测试用户";
                            break;
                    }
                    errStr = " err:\n".concat(e).concat(" ").concat(pushUserPO.getDeviceId());
                }
            }
            if (resultMessage.getResult() == 0) {//发送成功
                return MessageModel.success(requestSendBean.getTokens().size(), requestSendBean.getTokens().size(), StringUtils.isBlank(errStr) ? "发送成功\n" : "".concat(errStr).concat("\n"));
            }else {
                return MessageModel.errorMsg(requestSendBean.getTokens().size(), 0, resultMessage.getDesc().concat(errStr)+"\n");
            }
        } catch (Exception e) {
            log.error("VivoPush.pushSignleMessage Exception .", e);
            return MessageModel.errorMsg(requestSendBean.getTokens().size(), 0, e.getMessage()+"\n");
        }
    }

    /**
     * 这个方法暂时不用 都用单推
     *
     * @param requestSendBean
     * @param pushConfiguresPO
     * @return
     */
    private MessageModel pushAllMessage(RequestSendBean requestSendBean, PushConfiguresPO pushConfiguresPO) {
        try {
            Sender sender = new Sender(pushConfiguresPO.getVoAppSecret());//注册登录开发平台网站获取到的appSecret
            sender.initPool(20, 10);//设置连接池参数，可选项
            Result result = sender.getToken(Integer.parseInt(pushConfiguresPO.getVoAppId()), pushConfiguresPO.getVoAppKey());//注册登录开发平台网站获取到的appId和appKey

            log.info("vivo.pushAllMessage.pushConfiguresPO: {}", pushConfiguresPO);
            sender.setAuthToken(result.getAuthToken());

            //生产环境  0
            Result res = pushAllSend(requestSendBean, pushConfiguresPO, sender, customPushMode);
            jPushService.setPassThrougnMsg(requestSendBean, pushConfiguresPO);
            List<InvalidUser> invalidUsers = res.getInvalidUsers();
            InvalidUser invalidUser = res.getInvalidUser();
            String errStr = "";
            if (Objects.nonNull(invalidUsers) && invalidUsers.size()>0){
                Set<String> errors = invalidUsers.stream().map(s -> {
                    PushUserVO vo = new PushUserVO();
                    vo.setAppKey(requestSendBean.getAppKey());
                    vo.setManuToken(s.getUserid());
                    ResponseModel responseModel = pushUserService.queryByMaunToken(vo);
                    if (responseModel.isSuccess()) {
                        PushUserPO pushUserPO = (PushUserPO) responseModel.getRepData();
                        return pushUserPO.getDeviceId();
                    }
                    return "";
                }).collect(Collectors.toSet());
                errStr = " err:\n".concat(errors.toString());
            }
            if (Objects.nonNull(invalidUser)){
                PushUserVO vo = new PushUserVO();
                vo.setAppKey(requestSendBean.getAppKey());
                vo.setManuToken(invalidUser.getUserid());
                ResponseModel responseModel = pushUserService.queryByMaunToken(vo);
                if (responseModel.isSuccess()) {
                    PushUserPO pushUserPO = (PushUserPO) responseModel.getRepData();
                    String e = "";
                    switch (invalidUser.getStatus()){
                        case 1:
                            e = "userId不存在";
                            break;
                        case 2:
                            e = "卸载或者关闭了通知";
                            break;
                        case 3:
                            e = "90天不在线";
                            break;
                        case 4:
                            e = "非测试用户";
                            break;
                    }
                    errStr = " err:\n".concat(e).concat(" ").concat(pushUserPO.getDeviceId());
                }
            }

            if (res.getResult() == 0) {//发送成功
                return MessageModel.success(requestSendBean.getTokens().size(), requestSendBean.getTokens().size(), StringUtils.isBlank(errStr) ? "发送成功\n" : "".concat(errStr).concat("\n"));
            }else {
                return MessageModel.errorMsg(requestSendBean.getTokens().size(), 0, res.getDesc().concat(errStr)+"\n");
            }

        } catch (Exception e) {
            log.error("VivoPush.pushAllMessage Exception .", e);
            return MessageModel.errorMsg(requestSendBean.getTokens().size(), 0, e.getMessage()+"\n");
        }

    }


    private Result pushAllSend(RequestSendBean requestSendBean, PushConfiguresPO pushConfiguresPO, Sender sender, int pushMode) throws Exception {
        Result res = new Result();
        if (requestSendBean.getTokens().size() > 1) { //大于1 走全部推送
            Message saveList = new Message.Builder()
                    .notifyType(3)
                    .title(requestSendBean.getTitle())
                    .content(requestSendBean.getContent().length() > 49 ? requestSendBean.getContent().substring(0, 49) : requestSendBean.getContent())
                    .timeToLive(1000)
                    .skipType(2)
                    .skipContent("http://baidu.com")
                    .networkType(-1)
                    .requestId("1234567890123456")
                    .pushMode(pushMode)
                    .classification(1)//消息类型 0：运营类消息，1：系统类消息
                    .build();
            Result resultMessage = sender.saveListPayLoad(saveList);//发送保存群推消息请求
            log.info("VivoPush.pushAllMessage.resultMessage {}", resultMessage);
            if (resultMessage.getResult() == 0) {//发送成功
                String taskId = resultMessage.getTaskId();
                Set<String> regid = new HashSet<>();//构建批量推送用户群
                for (int i = 0; i < requestSendBean.getTokens().size(); i++) {
                    regid.add(requestSendBean.getTokens().get(i));
                }
                if (requestSendBean.getTokens().size() == 1) {
                    regid.add(requestSendBean.getTokens().get(0));
                }
                TargetMessage targetMessage = new TargetMessage.Builder().requestId("1234567890123457")
                        .regIds(regid).taskId(taskId).build();
                res = sender.sendToList(targetMessage);//批量推送给用户
                log.info("VivoPush.pushAllMessage.all.resultMessage {}", res);
                res.setTaskId(taskId);
            } else {
                res = resultMessage;
            }
        } else {
            Message singleMessage = new Message.Builder()
                    //该测试手机设备订阅推送所得的regid，且已添加为测试设备
                    .regId(requestSendBean.getTokens().get(0))
                    .notifyType(3)
                    .extra("callback", "http://open-appsp.anji-plus.com/push/pushVivoCallBack")
                    .extra("callback.param", "Vivo回调自定义参数")
                    .title(requestSendBean.getTitle())
                    .content(requestSendBean.getContent().length() > 49 ? requestSendBean.getContent().substring(0, 49) : requestSendBean.getContent())
                    .timeToLive(1000)
                    .skipType(4)
                    .classification(1)//消息类型 0：运营类消息，1：系统类消息
                    .skipContent("vpushscheme://com.vivo.push.notifysdk/detail")
                    .clientCustomMap(requestSendBean.getExtras())
                    .networkType(-1)
                    .requestId("1234567890123456")
                    .pushMode(pushMode)
                    .build();
            res = sender.sendSingle(singleMessage);
            log.info("VivoPush.pushAllMessage.Signle.resultMessage {}", res);
        }
        return res;
    }


    /**
     * 获取批量推送或全量推送返回的taskId对应的统计信息，单次查询的taskIds最多100个。
     *
     * @param taskIds
     * @param voAppSecret
     * @param voAppId
     * @param voAppKey
     * @return
     */
    public ResponseModel getVivoMiMessageStatus(String taskIds, String voAppSecret, String voAppId, String voAppKey) {
        Result result = null;
        try {
            Sender sender = new Sender(voAppSecret);//注册登录开发平台网站获取到的appSecret
            result = sender.getToken(Integer.parseInt(voAppId), voAppKey);//注册登录开发平台网站获取到的appId和appKey
            sender.setAuthToken(result.getAuthToken());
            sender.initPool(20, 10);//设置连接池参数，可选项
            Set<String> tasks = StringUtils.str2Set(taskIds, ",");
            result = sender.getStatistics(tasks);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResponseModel.successData(result);
    }


}
